﻿#include "GUIGeometryLoftingDialog.h"
#include "ui_GUIGeometryLoftingDialog.h"
#include "FITK_Kernel/FITKAppFramework/FITKAppFramework.h"
#include "FITK_Kernel/FITKAppFramework/FITKGlobalData.h"
#include "FITK_Kernel/FITKCore/FITKOperatorRepo.h"
#include "FITK_Component/FITKAcousticsModel/FITKAcousticsGeometryData.h"
#include "FITK_Interface/FITKInterfaceGeometry/FITKGeoInterfaceFactory.h"
#include "FITK_Interface/FITKInterfaceGeometry/FITKAbsGeoModelOperLine.h"
#include "FITK_Interface/FITKInterfaceGeometry/FITKAbsGeomTools.h"
#include "FITK_Interface/FITKInterfaceGeometry/FITKAbsGeoModelPoint.h"

#include "FITK_Interface/FITKInterfaceGeometry/FITKAbsGeoCommand.h"
#include "FITK_Interface/FITKInterfaceGeometry/FITKAbsGeoModelSurface.h"
#include "FITK_Interface/FITKInterfaceGeometry/FITKAbsGeoModelSolid.h"


#include "PickDataProvider/GUIPickInfo.h"
#include "FITK_Kernel/FITKCore/FITKActionOperator.h"
#include "OperatorsInterface/GraphEventOperator.h"

#include "PickDataProvider/PickedData.h"
#include "PickDataProvider/PickedDataProvider.h"
#include "GraphDataProvider/GraphDataCalculate.h"
#include <QMessageBox>

namespace GUI {

    GUIGeometryLoftingDialog::GUIGeometryLoftingDialog(Core::FITKActionOperator* oper, QWidget* parent)
        : GUIGeometryBaseDialog(nullptr, oper, parent), _ui(new Ui::GUIGeometryLoftingDialog)
    {
        _ui->setupUi(this);
        this->init();
    }

    GUIGeometryLoftingDialog::GUIGeometryLoftingDialog(Interface::FITKAbsGeoModelSegment* obj, Core::FITKActionOperator* oper, QWidget* parent)
        : GUIGeometryBaseDialog(obj, oper, parent), _ui(new Ui::GUIGeometryLoftingDialog)
    {
        _ui->setupUi(this);
        this->init();
    }

    GUIGeometryLoftingDialog::~GUIGeometryLoftingDialog()
    {
        if (_ui) {
            delete _ui;
            _ui = nullptr;
        }
    }
    void GUIGeometryLoftingDialog::init()
    {
        setWindowTitle(tr("Lofting"));//放样
        Acoustics::FITKAcousticsGeometryData* geometryData = FITKAPP->getGlobalData()->getGeometryData<Acoustics::FITKAcousticsGeometryData>();
        if (geometryData == nullptr) return;

        //设置默认选择类型
        QVariant selectType(GUI::GUIPickInfo::POBJGeometryEdge);//默认放样线
        _ui->stretch_type->setProperty("selectType", selectType);

        //获取数据
        QString name = geometryData->checkName(tr("Surface-1"));
        _ui->lineEdit_Name->setText(name);

        _ui->stretch_type->addItem("Multi-Sections Surface");//放样线 由多根线放样成面
        _ui->stretch_type->addItem("Multi-Sections Solid");//放样面 由多个面放样成体
    }

    QString GUIGeometryLoftingDialog::getNameText()
    {
        return _ui->lineEdit_Name->text();
    }

    void GUIGeometryLoftingDialog::pickFinishedOper()
    {
        //该类不实现
    }
    void GUIGeometryLoftingDialog::on_stretch_type_activated(int item)
    {
        //在切换拾取模式后，将清空对3维的操作
        GraphData::PickedDataProvider* provider = GraphData::PickedDataProvider::getInstance();
        if (provider == nullptr)return;
        QObject::disconnect(provider, SIGNAL(sig_pickedOver()), nullptr, nullptr);
        QObject::disconnect(provider, SIGNAL(sig_pickedData()), nullptr, nullptr);
        provider->clearPickedData();//清空拾取数据
        //拾取对象 关闭
        //拾取方式 空
        GUI::GUIPickInfoStru pickInfo = GUI::GUIPickInfo::GetPickInfo();
        pickInfo._pickObjType = GUI::GUIPickInfo::PickObjType(GUI::GUIPickInfo::POBJNone);
        pickInfo._pickMethod = GUI::GUIPickInfo::PickMethod(GUI::GUIPickInfo::PickMethod::PMNone);
        //设置拾取方式
        GUI::GUIPickInfo::SetPickInfo(pickInfo);
        //清空界面拾取的个数显示，重新初始化为0
        _ui->pick_num_1->setText("(0)");

        /*
        根据具体的选项，对创建对象的名称进行修改
        */
        Acoustics::FITKAcousticsGeometryData* geometryData = FITKAPP->getGlobalData()->getGeometryData<Acoustics::FITKAcousticsGeometryData>();
        if (geometryData == nullptr) return;
        QVariant selectType;
        QString name = "None";
        //选择要拾取的类型，这里的拾取类型，不是界面上的Type
        if (item == 0)
        {
            name = geometryData->checkName(tr("Surface-1"));
            selectType.setValue(GUI::GUIPickInfo::POBJGeometryEdge);//拾取方式线 线放样成面
        }
        else if (item == 1)
        {
            name = geometryData->checkName(tr("Solid-1"));
            selectType.setValue(GUI::GUIPickInfo::POBJGeometryFace);//拾取方式面->由面放样成体
        }
        //设置界面
        _ui->lineEdit_Name->setText(name);
        //设置当前选择
        _ui->stretch_type->setProperty("selectType", selectType);
    }

    void GUIGeometryLoftingDialog::on_pushButton_OK_clicked()
    {
        //获取当前拾取到的数据
        QList<Interface::VirtualShape> spList = this->getVirtualShape();

        QString checkStr = this->checkArgc(spList);//检查参数

        if (checkStr.size() != 0)
        {
            //错误信息汇报
            QMessageBox msgBox;
            msgBox.setIcon(QMessageBox::Warning);  // 设置消息框图标为警告图标
            msgBox.setWindowTitle(tr("warning"));
            msgBox.setText(checkStr);
            msgBox.setStandardButtons(QMessageBox::Ok);  // 设置标准按钮
            msgBox.setDefaultButton(QMessageBox::Ok);  // 设置默认按钮
            int ret = msgBox.exec();//事件循环
            return;
        }
        //获取当前放样模式
        QVariant var = _ui->stretch_type->property("selectType");
        if (var.canConvert<GUI::GUIPickInfo::PickObjType>())
        {
            GUI::GUIPickInfo::PickObjType types = var.value<GUI::GUIPickInfo::PickObjType>();
            switch (types)
            {
            case GUI::GUIPickInfo::POBJGeometryEdge:
            {
                this->createGeometryObj(Interface::FITKGeoEnum::FITKGeometryComType::FGTMultiSectionSurface);
                Interface::FITKAbsGeoModelMultiSectionSurface*surfaceP = dynamic_cast<Interface::FITKAbsGeoModelMultiSectionSurface*>(_obj);
                if (surfaceP == nullptr) return;
                surfaceP->setSections(spList);
                surfaceP->setDataObjectName(_ui->lineEdit_Name->text());//更新体名称
                break;
            }
            case GUI::GUIPickInfo::POBJGeometryFace:
            {
                this->createGeometryObj(Interface::FITKGeoEnum::FITKGeometryComType::FGTMultiSectionSolid);
                Interface::FITKAbsGeoModelMultiSectionSolid*solidP = dynamic_cast<Interface::FITKAbsGeoModelMultiSectionSolid*>(_obj);
                if (solidP == nullptr) return;
                solidP->setSections(spList);
                solidP->setDataObjectName(_ui->lineEdit_Name->text());//更新体名称
                break;
            }
            default:
                break;
            }
        }

        if (_isCreate)
        {
            if (!this->createObjData())
            {
                return;
            }
        }
        else
        {
            if (!this->editObjData())
                return;
        }
        if (_oper && _obj) {
            _oper->setArgs("objID", _obj->getDataObjectID());
        }
        this->accept();
    }


    void GUIGeometryLoftingDialog::on_pushButton_Cancel_clicked()
    {
        _oper->setArgs("objID", -1);
        this->accept();
    }
    void GUIGeometryLoftingDialog::on_button_pick_clicked()
    {
        //拾取方式 单独数据拾取方式。（点选+追加拾取）    
        //获取拾取器，绑定拾取结束信号
        GraphData::PickedDataProvider* pickProvider = GraphData::PickedDataProvider::getInstance();
        //清除拾取对象所有的连接
        if (pickProvider != nullptr)
        {
            QObject::disconnect(pickProvider, SIGNAL(sig_pickedOver()), nullptr, nullptr);
            QObject::disconnect(pickProvider, SIGNAL(sig_pickedData()), nullptr, nullptr);
            //绑定信号
            connect(pickProvider, &GraphData::PickedDataProvider::sig_pickedData, this, &GUIGeometryLoftingDialog::Onpick1InProcess);
        }
        GUI::GUIPickInfoStru pickInfo = GUI::GUIPickInfo::GetPickInfo();

        //也需要清空
        _ui->pick_num_1->setText("(0)");

        //获取当前放样模式
        QVariant var = _ui->stretch_type->property("selectType");
        if (var.canConvert<GUI::GUIPickInfo::PickObjType>())
        {
            GUI::GUIPickInfo::PickObjType stretchType = var.value<GUI::GUIPickInfo::PickObjType>();
            switch (stretchType)
            {
            case GUI::GUIPickInfo::POBJGeometryEdge:
                pickInfo._pickObjType = GUI::GUIPickInfo::PickObjType(GUI::GUIPickInfo::POBJGeometryEdge);//选取线
                pickInfo._pickMethod = GUI::GUIPickInfo::PickMethod(GUI::GUIPickInfo::PickMethod::PMIndividually);//可多选
                break;
            case GUI::GUIPickInfo::POBJGeometryFace:
                pickInfo._pickObjType = GUI::GUIPickInfo::PickObjType(GUI::GUIPickInfo::POBJGeometryFace);//选取面
                pickInfo._pickMethod = GUI::GUIPickInfo::PickMethod(GUI::GUIPickInfo::PickMethod::PMIndividually);
                break;
            default:
                break;
            }
        }
        //设置拾取方式
        GUI::GUIPickInfo::SetPickInfo(pickInfo);
    }
    void GUIGeometryLoftingDialog::Onpick1InProcess()
    {
        int pkNum=this->getPickNum();
        QString number = "(" + QString::number(pkNum) + ")";
        _ui->pick_num_1->setText(number);
    }
    QList<Interface::VirtualShape> GUIGeometryLoftingDialog::getVirtualShape()
    {
        //获取拾取数据
        GraphData::PickedDataProvider* provider = GraphData::PickedDataProvider::getInstance();
        if (provider == nullptr)return {};
        disconnect(provider, SIGNAL(sig_pickedOver()), this, SLOT(slotPickOverEvent()));
        QList<GraphData::PickedData*> pickList = provider->getPickedList();
        QList<Interface::VirtualShape> Shape;
        for (GraphData::PickedData* pickData : pickList) {
            if (pickData == nullptr)continue;
            int cmdID = pickData->getPickedDataObjId();
            QHash<int, int>OtherIDs = pickData->getPickedOtherIDs();
            for (int i : pickData->getPickedIds())
            {
                if (OtherIDs.contains(i) == true)
                {
                    Interface::VirtualShape temp(cmdID, i, OtherIDs.value(i));
                    Shape.push_back(temp);
                }
            }
        }
        return Shape;
    }
  
    int GUIGeometryLoftingDialog::getPickNum()
    {
        int pick_num = 0;
        GraphData::PickedDataProvider* provider = GraphData::PickedDataProvider::getInstance();
        if (provider == nullptr)return 0;
        disconnect(provider, SIGNAL(sig_pickedOver()), this, SLOT(slotPickOverEvent()));
        QList<GraphData::PickedData*> pickList = provider->getPickedList();//拾取到那些对象的IDlist

        //计算获取到多少个几何对象
        for (GraphData::PickedData *data : pickList)
        {
            QList<int>temp = data->getPickedIds();
            pick_num += temp.size();
        }
        return pick_num;
    }

    QString GUIGeometryLoftingDialog::checkArgc(QList<Interface::VirtualShape> &spList)
    {
        if (spList.size() == 0)
        {
            return tr("No pick");
        }
        return "";
    }

}